package com.wjm.api.homework;

import java.lang.reflect.Field;

/**
 * Data:2022年07月31日
 * Author:wjm
 * Content: Reflect反射机制练习（修改String）
 *
 *
 * 题目：
 *      需求如下，已知String str = ”wjm爱吃cwt“，
 *      要求在不改变地址值的情况下（hashcode值不变），改变其存储内容。str = ”小翁爱吃cwt“
 *
 *
 * 思路：
 *     String的本质是一个final修饰的char[]数组，在String类中，这个数组叫value，
 *     在源码中的表示：private final char value[];
 *     由于String的不可变性，平时我们在修改Sting内容的时候其实是new了一个新的对象，然后将str引用指向新对象
 *     所以想在不改变地址值的情况下，改变内容，就需要使用反射机制，因为反射机制可以破坏类的封装性
 *
 * 步骤：
 *     1.先通过反射获取char[]数组
 *     2.然后针对获取的数组赋值
 *
 */
public class HomeWork1 {
    public static void main(String[] args) throws Exception {
        String str = "wjm爱吃cwt";

        System.out.println("改变前的hashcode值："+str.hashCode());

        /*
        * 思路：
        *     String的本质是一个final修饰的char[]数组，在String类中，这个数组叫value，
        *     在源码中的表示：private final char value[];
        *     由于String的不可变性，平时我们在修改Sting内容的时候其实是new了一个新的对象，然后将str引用指向新对象
        *     所以想在不改变地址值的情况下，改变内容，就需要使用反射机制，因为反射机制可以破坏类的封装性
        *
        * 步骤：
        *     1.先通过反射获取char[]数组
        *     2.然后针对获取的数组赋值
        *
        * */
        //获取类对象
        Class c = str.getClass();

        //获取指定名称的属性
        Field field = c.getDeclaredField("value");

        //因为该属性是private，所以需要先对该属性进行暴力反射，能对其设置值
        field.setAccessible(true);

        //给属性设值,因为value是char数组所以不能之间传字符串
        //field.set(str,"小翁爱吃cwt");
        field.set(str,new char[]{'小','翁','爱','吃','c','w','t'});
        System.out.println(str);
        System.out.println("修改后的hashcode："+str.hashCode());




    }
}
